/*
 * Vector2D.cpp
 *
 *  Created on: 22 Oct 2012
 *      Author: Guy
 */

#include "Vector2D.h"
#include <cmath>

using namespace SolidityEngine;

Vector2D::Vector2D():
	_x(.0f),
	_y(.0f)
{}

Vector2D::Vector2D(float x, float y):
	_x(x),
	_y(y)
{
}

float Vector2D::X() const{
	return _x;
}

float Vector2D::Y() const{
	return _y;
}

float& Vector2D::X() {
	return _x;
}

float& Vector2D::Y() {
	return _y;
}

Vector2D Vector2D::Normalized() const{
    Vector2D vector=Vector2D(*this);
    float scale=sqrt(pow(_x,2.0)+pow(_y,2.0));
    return vector*(1.0/scale);
}

void Vector2D::Normalize(){
    float scale=sqrt(pow(_x,2.0)+pow(_y,2.0));
    _x*=(1.0/scale);
    _y*=(1.0/scale);
}

Vector2D Vector2D::operator+(const Vector2D& rhs) const{
	Vector2D vector;
	vector.X()=this->_x+rhs.X();
	vector.Y()=this->_y+rhs.Y();
	return vector;
}

Vector2D Vector2D::operator-(const Vector2D& rhs) const{
	Vector2D vector;
	vector.X()=this->_x-rhs.X();
	vector.Y()=this->_y-rhs.Y();
	return vector;
}

Vector2D operator*(float lhs, const Vector2D& rhs){
    Vector2D vector;
    vector.X()=rhs.X()*lhs;
    vector.Y()=rhs.Y()*lhs;
    return vector;
}

Vector2D Vector2D::operator*(float rhs) const{
    Vector2D vector;
    vector.X()=this->_x*rhs;
    vector.Y()=this->_y*rhs;
    return vector;
}

float Vector2D::Length() const{
	return sqrt(pow(_x,2.0f)+pow(_y,2.0f));
}

float Vector2D::Distance(const Vector2D& v1, const Vector2D& v2){
	return (v2-v1).Length();
}

Vector2D Vector2D::Zero(){
	return Vector2D(0.0f,0.0f);
}

Vector2D Vector2D::Up(){
	return Vector2D(0.0f,-1.0f);
}

Vector2D Vector2D::Down(){
	return Vector2D(0.0f,1.0f);
}

Vector2D Vector2D::Left(){
	return Vector2D(-1.0f,0.0f);
}

Vector2D Vector2D::Right(){
	return Vector2D(1.0f,0.0f);
}

float Vector2D::Dot(const Vector2D& v1, const Vector2D& v2){
    return v1.X()*v2.X()+v1.Y()*v2.Y();
}

//given 2 vectors and a point, calculates the point on the line between vectors that is nearest to the point.
Vector2D Vector2D::NearestPoint(const Vector2D& v1, const Vector2D& v2, const Vector2D& point){

    float T = Vector2D::Dot(point-v1,v2-v1)/((v2-v1).Length()*(v2-v1).Length());
    return v1 + (v2-v1) * T;
}

Vector2D Vector2D::Lerp(const Vector2D& v1, const Vector2D& v2, float t){
    return v1+(v2-v1)*t;
}

bool Vector2D::operator!=(const Vector2D& rhs) const {
    if (*this==rhs) return false;
    return true;
}

bool Vector2D::operator==(const Vector2D& rhs) const{
    if((this->_x==rhs._x) && (this->_y==rhs._y)){
        return true;
    }
    return false;
}

Vector2D::~Vector2D() {
}
